import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
} from '@vben/types';
import type { RouteMeta } from 'vue-router';

import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';

import { array2tree } from '@axolo/tree-array';
import { ElMessage } from 'element-plus';

import { getMenuListByRole } from '#/api/sys/menu';
import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';

interface RouteItem {
  id?: number;
  parentId?: number;
  path: string;
  component: any;
  meta: RouteMeta;
  name?: string;
  alias?: string | string[];
  redirect?: string;
  caseSensitive?: boolean;
  children?: RouteItem[];
  permission?: string;
}

const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');

async function generateAccess(options: GenerateMenuAndRoutesOptions) {
  const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
  };

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      ElMessage({
        duration: 1500,
        message: `${$t('common.loadingMenu')}...`,
      });
      const menuData = await getMenuListByRole();

      // const menuData = [
      //   {
      //     id: 2,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 1,
      //     path: '/dashboard',
      //     name: 'Dashboard',
      //     redirect: '',
      //     component: '/dashboard/workspace/index',
      //     sort: 0,
      //     disabled: null,
      //     meta: {
      //       title: $t('routename.dashboard.analytics'),
      //       icon: 'ant-design:home-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 4,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/menu',
      //     name: 'MenuManagement',
      //     redirect: '',
      //     component: '/system/menu/index',
      //     sort: 1,
      //     disabled: null,
      //     meta: {
      //       title: '菜单管理',
      //       icon: 'ant-design:bars-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 1,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 1,
      //     parentId: 1_000_000,
      //     path: '/dashboard_dir',
      //     name: 'DashBoardDir',
      //     redirect: '',
      //     component: 'LAYOUT',
      //     sort: 1,
      //     disabled: null,
      //     meta: {
      //       title: '管理中心',
      //       icon: 'ic:baseline-view-in-ar',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 0,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 5,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/role',
      //     name: 'RoleManagement',
      //     redirect: '',
      //     component: '/system/role/index',
      //     sort: 2,
      //     disabled: null,
      //     meta: {
      //       title: $t('routename.system.role'),
      //       icon: 'ant-design:user-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 11,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 1,
      //     parentId: 10,
      //     path: '/profile',
      //     name: 'Profile',
      //     redirect: '',
      //     component: '/system/profile/index',
      //     sort: 3,
      //     disabled: null,
      //     meta: {
      //       title: '用户个人信息',
      //       icon: 'ant-design:profile-outlined',
      //       hideMenu: true,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 6,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/user',
      //     name: 'UserManagement',
      //     redirect: '',
      //     component: '/system/user/index',
      //     sort: 3,
      //     disabled: null,
      //     meta: {
      //       title: $t('routename.system.user'),
      //       icon: 'ant-design:user-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 7,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/department',
      //     name: 'DepartmentManagement',
      //     redirect: '',
      //     component: '/system/department/index',
      //     sort: 4,
      //     disabled: null,
      //     meta: {
      //       title: '部门管理',
      //       icon: 'ic:outline-people-alt',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 8,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/api',
      //     name: 'APIManagement',
      //     redirect: '',
      //     component: '/system/api/index',
      //     sort: 5,
      //     disabled: null,
      //     meta: {
      //       title: '接口管理',
      //       icon: 'ant-design:api-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 9,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/dictionary',
      //     name: 'DictionaryManagement',
      //     redirect: '',
      //     component: '/system/dictionary/index',
      //     sort: 6,
      //     disabled: null,
      //     meta: {
      //       title: '字典管理',
      //       icon: 'ant-design:book-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: true,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 12,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/oauth',
      //     name: 'OauthManagement',
      //     redirect: '',
      //     component: '/system/oauth/index',
      //     sort: 6,
      //     disabled: null,
      //     meta: {
      //       title: '第三方登录管理',
      //       icon: 'ant-design:unlock-filled',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 13,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/token',
      //     name: 'TokenManagement',
      //     redirect: '',
      //     component: '/system/token/index',
      //     sort: 7,
      //     disabled: null,
      //     meta: {
      //       title: '令牌管理',
      //       icon: 'ant-design:lock-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 14,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/position',
      //     name: 'PositionManagement',
      //     redirect: '',
      //     component: '/system/position/index',
      //     sort: 8,
      //     disabled: null,
      //     meta: {
      //       title: '职位管理',
      //       icon: 'ic:twotone-work-outline',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 15,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/task',
      //     name: 'TaskManagement',
      //     redirect: '',
      //     component: '/system/task/index',
      //     sort: 8,
      //     disabled: null,
      //     meta: {
      //       title: '定时任务管理',
      //       icon: 'ic:baseline-access-alarm',
      //       hideMenu: true,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Job',
      //     permission: '',
      //   },
      //   {
      //     id: 16,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 2,
      //     parentId: 3,
      //     path: '/configuration',
      //     name: 'ConfigurationManagement',
      //     redirect: '',
      //     component: '/system/configuration/index',
      //     sort: 9,
      //     disabled: null,
      //     meta: {
      //       title: '参数管理',
      //       icon: 'carbon:data-2',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 1,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 3,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 1,
      //     parentId: 1_000_000,
      //     path: '/system',
      //     name: 'SystemManagement',
      //     redirect: '',
      //     component: 'LAYOUT',
      //     sort: 999,
      //     disabled: null,
      //     meta: {
      //       title: '系统管理',
      //       icon: 'ant-design:tool-outlined',
      //       hideMenu: false,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 0,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      //   {
      //     id: 10,
      //     createdAt: null,
      //     updatedAt: null,
      //     trans: '',
      //     level: 1,
      //     parentId: 1_000_000,
      //     path: '/other',
      //     name: 'OtherPages',
      //     redirect: '',
      //     component: 'LAYOUT',
      //     sort: 1000,
      //     disabled: null,
      //     meta: {
      //       title: '其他页面',
      //       icon: 'ant-design:question-circle-outlined',
      //       hideMenu: true,
      //       hideBreadcrumb: false,
      //       ignoreKeepAlive: false,
      //       hideTab: false,
      //       frameSrc: '',
      //       carryParam: false,
      //       hideChildrenInMenu: false,
      //       affix: false,
      //       dynamicLevel: 20,
      //       realPath: '',
      //     },
      //     menuType: 0,
      //     serviceName: 'Core',
      //     permission: '',
      //   },
      // ];
      menuData.data.forEach((val, _idx, _arr) => {
        if (val.component === 'LAYOUT') {
          val.component = '';
        }

        val.meta.hideInMenu = val.meta.hideMenu as any;
        val.meta.hideInTab = val.meta.hideTab as any;
        val.meta.hideInBreadcrumb = val.meta.hideBreadcrumb as any;
        val.meta.keepAlive = !val.meta.ignoreKeepAlive as boolean;
        val.meta.maxNumOfOpenTab = val.meta.dynamicLevel as any;
        val.meta.affixTab = val.meta.affix as any;
      });
      const treeData: RouteItem[] = array2tree(
        menuData.data.filter((val) => val.path !== ''),
      ) as RouteItem[];
      treeData.forEach((val, idx, arr) => {
        if (val.component === '' && arr[idx]) {
          arr[idx].component = 'BasicLayout';
        }
      });
      return treeData;
    },
    forbiddenComponent,
    layoutMap,
    pageMap,
  });
}

export { generateAccess };
